package com.allenlee.mvphelper.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import com.qmuiteam.qmui.util.QMUIDisplayHelper;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
import com.allenlee.mvphelper.R;

/**
 * @author : lifei
 * 创建时间： 19-12-12
 * 更改时间： 19-12-12
 * Email : allen.lee723@qq.com
 * @version :
 * Description： 圆圈扩散水波动画效果
 */
public class SpreadView extends AppCompatTextView {

    private static final String TAG = SpreadView.class.getSimpleName();

    // 自定义属性
    private int spreadColor;
    // 是否扩散
    private boolean isSpread;
    // 是否旋转
    private boolean isRotate;
    // 波浪扩散的速度
    private int spreadDelay;
    // 波浪透明度
    private int spreadAlpha;
    // 中心圆半径百分比
    private float centerRadiusPercent;

    private Context mContext;
    // 中心圆 paint
    private Paint centerPaint;
    // 文字 paint
    private Paint tipsPaint;
    // 中心圆半径
    private int centerRadius;
    // 圆心 x
    private int centerX;
    // 圆心 y
    private int centerY;
    // 扩散圆 paint
    private Paint spreadPaint;
    // View 宽
    private float mWidth;
    // View 高
    private float mHeight;
    // 用来放波浪的容器
    private List<Circle> spreadList;
    // 用来放被移除的波浪
    private List<Circle> spreadPool;

    // 中心圆背景
    private static final int CENTER_BACKGROUND_MODE_PIC = 0;
    private static final int CENTER_BACKGROUND_MODE_COLOR = 1;
    private static final int CENTER_BACKGROUND_MODE_XML = 2;
    private static final int CENTER_BACKGROUND_MODE_DEFAULT = 3;
    private int mCenterBackgroundMode = CENTER_BACKGROUND_MODE_DEFAULT;
    private Bitmap mCenterBitmap;
    private int mCenterColor;
    private Rect srcCenterRect;
    private Rect dstCenterRect;

    private float currentDegree;
    private float maxStroke;

    public SpreadView(Context context) {
        this(context, null, 0);
    }

    public SpreadView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SpreadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = getContext();

        if (attrs != null) {
            initTypedArray(context, attrs, defStyleAttr);
        }

        initPaint();
        init();
    }

    private void initTypedArray(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SpreadView, defStyleAttr, 0);
        // 中心圆背景
        Drawable centerBackground = typedArray.getDrawable(R.styleable.SpreadView_spread_centerBackground);
        resolveCenterDrawable(centerBackground);

        spreadColor = typedArray.getColor(R.styleable.SpreadView_spread_spreadColor,
            ContextCompat.getColor(context, R.color.btn_filled_blue_bg_normal));
        isSpread = typedArray.getBoolean(R.styleable.SpreadView_spread_start, false);
        isRotate = typedArray.getBoolean(R.styleable.SpreadView_spread_rotate, false);
        spreadDelay = typedArray.getInteger(R.styleable.SpreadView_spread_delayMilliseconds, 10);
        spreadAlpha = typedArray.getInt(R.styleable.SpreadView_spread_alpha, 255);
        centerRadiusPercent = typedArray.getFloat(R.styleable.SpreadView_spread_centerRadius_percent, 0.25f);
        if (centerRadiusPercent > 1.0f) {
            centerRadiusPercent = 1.0f;
        }

        typedArray.recycle();
    }

    private void initPaint() {
        centerPaint = new Paint();
        centerPaint.setColor(getResources().getColor(R.color.qmui_config_color_white));
        centerPaint.setAntiAlias(true);

        tipsPaint = new Paint();
        tipsPaint.setColor(getResources().getColor(R.color.qmui_config_color_black));
        tipsPaint.setAntiAlias(true);
        tipsPaint.setStyle(Paint.Style.FILL);
        tipsPaint.setTextSize(QMUIDisplayHelper.sp2px(getContext(), 12));
        tipsPaint.setTextAlign(Paint.Align.CENTER);

        spreadPaint = new Paint();
        spreadPaint.setAntiAlias(true);
        spreadPaint.setAlpha(spreadAlpha);
        spreadPaint.setColor(spreadColor);
        spreadPaint.setStyle(Paint.Style.STROKE);
    }

    private void init() {
        spreadList = new ArrayList<>();
        // 添加第一个波浪
        Circle circle = new Circle(0, spreadAlpha);
        spreadList.add(circle);
        spreadPool = new ArrayList<>();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawInCircle(canvas);
        super.onDraw(canvas);
    }

    private void drawInCircle(Canvas canvas) {

        // 画波浪
        if (isSpread) {
            for (Circle circle : spreadList) {
                spreadPaint.setAlpha(circle.alpha);
                spreadPaint.setStrokeWidth(circle.stroke);
                // 绘制扩散的圆
                canvas.drawCircle(centerX, centerY, centerRadius + spreadPaint.getStrokeWidth() / 2, spreadPaint);
                // 每次扩散圆半径递增，圆透明度递减
                double alpha = spreadAlpha - spreadAlpha * ((circle.stroke + centerRadius) / ((double) mWidth / 2));
                circle.alpha = (int) alpha;

                // 修改这个值控制速度
                circle.stroke++;
            }

            if (spreadList.size() > 0) {

                // 控制第二个波浪出来的间距
                if (spreadList.get(spreadList.size() - 1).stroke > maxStroke / 3) {
                    if (spreadPool.size() > 0) {
                        spreadList.add(spreadPool.get(0));
                        spreadPool.remove(0);
                    } else {
                        spreadList.add(new Circle(0, spreadAlpha));
                    }
                }

                // 当最外层的波浪超出 View 的宽度后删除
                if (spreadList.get(0).stroke > maxStroke) {
                    spreadList.get(0).stroke = 0;
                    spreadList.get(0).alpha = spreadAlpha;
                    spreadPool.add(spreadList.get(0));
                    spreadList.remove(0);
                }
            }
        }

        // 旋转画布
        if (isRotate) {
            canvas.save();
            if (currentDegree >= 360) {
                currentDegree = 0;
            }
            canvas.rotate(currentDegree, centerX, centerY);
            currentDegree++;
        }

        // 画中间的圆
        if (mCenterBackgroundMode == CENTER_BACKGROUND_MODE_PIC || mCenterBackgroundMode == CENTER_BACKGROUND_MODE_XML) {
            // 图片
            if (srcCenterRect == null) {
                srcCenterRect = new Rect(0, 0, mCenterBitmap.getWidth(), mCenterBitmap.getHeight());
            }
            if (dstCenterRect == null) {
                dstCenterRect = new Rect(centerX - centerRadius, centerY - centerRadius, centerX + centerRadius, centerY + centerRadius);
            }
            canvas.drawBitmap(mCenterBitmap, srcCenterRect, dstCenterRect, centerPaint);
        } else if (mCenterBackgroundMode == CENTER_BACKGROUND_MODE_COLOR) {
            // 色值
            centerPaint.setColor(mCenterColor);
            canvas.drawCircle(centerX, centerY, centerRadius, centerPaint);
        } else {
            // 其他或者未设置
            centerPaint.setColor(Color.GRAY);
            canvas.drawCircle(centerX, centerY, centerRadius, centerPaint);
        }

        if (isRotate) {
            canvas.restore();
        }

        if (isSpread || isRotate) {
            postInvalidateDelayed(spreadDelay);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "尺寸变化 onSizeChanged: ");
        // 圆心位置
        centerX = w / 2;
        centerY = h / 2;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d(TAG, "尺寸变化 onMeasure: ");
        int myWidthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int myWidthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int myHeightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int myHeightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        // 获取宽度
        if (myWidthSpecMode == MeasureSpec.EXACTLY) {
            // match_parent
            mWidth = myWidthSpecSize;
        } else {
            // wrap_content
            mWidth = QMUIDisplayHelper.dp2px(mContext, 120);
        }

        // 获取高度
        if (myHeightSpecMode == MeasureSpec.EXACTLY) {
            mHeight = myHeightSpecSize;
        } else {
            // wrap_content
            mHeight = QMUIDisplayHelper.dp2px(mContext, 120);
        }

        updateCenterRadius();

        // 设置该view的宽高
        setMeasuredDimension((int) mWidth, (int) mHeight);
    }

    /*@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (event.getX() < (mWidth / 2 - centerRadius) || event.getX() > (mWidth / 2 + centerRadius)) {
                return true;
            }
            if (event.getY() < (mHeight / 2 - centerRadius) || event.getY() > mHeight / 2 + centerRadius) {
                return true;
            }
        }

        return super.onTouchEvent(event);
    }*/

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (event.getX() < (mWidth / 2 - centerRadius) || event.getX() > (mWidth / 2 + centerRadius)) {
                return true;
            }
            if (event.getY() < (mHeight / 2 - centerRadius) || event.getY() > mHeight / 2 + centerRadius) {
                return true;
            }
        }
        return super.dispatchTouchEvent(event);
    }

    /**
     * 更新中心圆的半径大小
     */
    private void updateCenterRadius() {
        centerRadius = (int) (mWidth * centerRadiusPercent);
        /*if (mCenterBitmap != null && Math.min(mCenterBitmap.getWidth() / 2, mCenterBitmap.getHeight() / 2) < centerRadius) {
            centerRadius = Math.min(mCenterBitmap.getWidth() / 2, mCenterBitmap.getHeight() / 2);
        }*/
        maxStroke = mWidth / 2 - centerRadius;
    }

    /**
     * 设置扩散状态
     * @param isSpread 是否扩散
     */
    public void setSpread(boolean isSpread) {
        if (this.isSpread == isSpread) {
            return;
        }
        this.isSpread = isSpread;
        if (!this.isSpread) {
            spreadList.clear();
            spreadList.add(new Circle(0, spreadAlpha));
        }
        invalidate();
    }

    /**
     * 是否扩散中
     */
    public boolean isSpread() {
        return isSpread;
    }

    public int getSpreadAlpha() {
        return spreadAlpha;
    }

    public void setSpreadAlpha(int spreadAlpha) {
        this.spreadAlpha = spreadAlpha;
        invalidate();
    }

    /**
     * 解析 drawable
     * @param drawable drawable
     */
    private void resolveCenterDrawable(Drawable drawable) {
        if (mCenterBitmap != null) {
            mCenterBitmap = null;
        }

        if (drawable != null) {
            if (drawable instanceof BitmapDrawable) {
                // 设置了一张图片
                mCenterBitmap = ((BitmapDrawable) drawable).getBitmap();
                mCenterBackgroundMode = CENTER_BACKGROUND_MODE_PIC;
            } else if (drawable instanceof GradientDrawable) {
                // XML
                mCenterBitmap = drawable2Bitmap(drawable);
                mCenterBackgroundMode = CENTER_BACKGROUND_MODE_XML;
            } else if (drawable instanceof ColorDrawable) {
                // 色值
                mCenterColor = ((ColorDrawable) drawable).getColor();
                mCenterBackgroundMode = CENTER_BACKGROUND_MODE_COLOR;
            } else {
                // 其他形式
                mCenterBackgroundMode = CENTER_BACKGROUND_MODE_DEFAULT;
            }
        } else {
            mCenterBackgroundMode = CENTER_BACKGROUND_MODE_DEFAULT;
        }
    }

    // spread_centerBackground
    public void setCenterBackgroundResource(@DrawableRes int resId) {
        Drawable drawable = getContext().getResources().getDrawable(resId);
        resolveCenterDrawable(drawable);
        updateCenterRadius();
        invalidate();
    }

    public void setCenterBackgroundDrawable(Drawable background) {
        resolveCenterDrawable(background);
        updateCenterRadius();
        invalidate();
    }

    /**
     * Drawable 转 Bitmap
     * @param drawable Drawable
     * @return Bitmap
     */
    private Bitmap drawable2Bitmap(Drawable drawable) {
        // 取 drawable 的长宽
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

    public void setRotate(boolean isRotate) {
        if (this.isRotate == isRotate) {
            return;
        }
        this.isRotate = isRotate;
        invalidate();
    }

    public int getCenterRadius() {
        return this.centerRadius;
    }

    public boolean isRotate() {
        return this.isRotate;
    }

    class Circle {

        int stroke;
        int alpha;

        Circle(int stroke, int alpha) {
            this.stroke = stroke;
            this.alpha = alpha;
        }
    }
}